#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "het_ringbuf.h"
#include "het_chatgpt.h"
RingBuffer* rb_createRingBuffer(RingBuffer *rbBuf,char *name,size_t size,RK_CACHE_TYPE_MODE_E cacheType) {
    rbBuf->buffer = (char*)malloc(size);
    rbBuf->name = name;
    rbBuf->bufferAddr = rbBuf->buffer;
    rbBuf->bufferSize = size;
    rbBuf->head = 0;
    rbBuf->tail = 0;
    rbBuf->minValue = 0;
    rbBuf->cacheType = cacheType;
    memset(rbBuf->bufferAddr, 0, size);
    return rbBuf;
}

void rb_destroyRingBuffer(RingBuffer *rbBuf) {
    pthread_mutex_destroy(&rbBuf->mutex);
    if(rbBuf){
        if(rbBuf->buffer)
            free(rbBuf->buffer);
        
        free(rbBuf);
        rbBuf = NULL;
    }
}

void rb_setMinValue(RingBuffer *rbBuf, size_t value) {
    rbBuf->minValue = value;
}

void rb_reset(RingBuffer *rbBuf) {
    rbBuf->head = 0;
    rbBuf->tail = 0;
    rbBuf->length  = 0;
    rbBuf->bufferAddr = rbBuf->buffer;
    memset(rbBuf->buffer, 0, rbBuf->bufferSize);
}

int rb_push(RingBuffer *rbBuf, const char *data, size_t length) {
    int oldsize;
    //设置两次写入长度
    uint32_t write_size_a, write_size_b ;
    if(!rbBuf)
        return -1;
    if(!data)
        return -2;
    if(!length)
        return -3;
    //如果不够存储空间存放新数据,返回错误
    oldsize = rbBuf->length;
    if((rbBuf->length + length) > (rbBuf->bufferSize)){
	    //HET_LOGE("rb_push %s full %d -> %d \n",rbBuf->name,rbBuf->bufferSize,rbBuf->length + length);
        //return -4;
        if(rbBuf->bufferSize > (rbBuf->length +1)){
            length = rbBuf->bufferSize - rbBuf->length -1;
        }else{
            return  0;
        }
    }
    //如果顺序可用长度小于需写入的长度，需要将数据拆成两次分别写入
    if((rbBuf->bufferSize - rbBuf->tail) < length)
    {
        write_size_a = rbBuf->bufferSize - rbBuf->tail ;//从尾指针开始写到储存数组末尾
        write_size_b = length - write_size_a ;//从储存数组开头写数据
        //分别拷贝a、b段数据到储存数组中
        memcpy(rbBuf->bufferAddr + rbBuf->tail, data, write_size_a);
        memcpy(rbBuf->bufferAddr, data + write_size_a, write_size_b);
        rbBuf->length += length ;//记录新存储了多少数据量
        rbBuf->tail = write_size_b ;//重新定位尾指针位置
    }
    else//如果顺序可用长度大于或等于需写入的长度，则只需要写入一次
    {
        write_size_a = length ;//从尾指针开始写到储存数组末尾
        memcpy(rbBuf->bufferAddr + rbBuf->tail, data, write_size_a);
        rbBuf->length += length ;//记录新存储了多少数据量
        rbBuf->tail += write_size_a ;//重新定位尾指针位置
        if(rbBuf->tail == rbBuf->bufferSize)
            rbBuf->tail = 0 ;//如果写入数据后尾指针刚好写到数组尾部，则回到开头，防止越位
    }
	//HET_LOGD("rb_push %s %d -> %d \n",rbBuf->name,oldsize,rbBuf->length);
    return length;
}

int rb_pop(RingBuffer *rbBuf,char *data, size_t length) {
    int oldsize = rbBuf->length,newsize;
    uint32_t Read_size_a, Read_size_b ;
    if(rbBuf->length == 0){
        return 0;
    }
    if(length > rbBuf->length){
        length = rbBuf->length;
    }
    if(length > (rbBuf->bufferSize - rbBuf->head))
    {
        Read_size_a = rbBuf->bufferSize - rbBuf->head ;
        Read_size_b = length - Read_size_a ;
        if(data){
            memcpy(data, rbBuf->bufferAddr + rbBuf->head, Read_size_a);
            memcpy(data + Read_size_a, rbBuf->bufferAddr, Read_size_b);
        }
        rbBuf->length -= length ;//记录剩余数据量
        rbBuf->head = Read_size_b ;//重新定位头指针位置
    }
    else
    {
        Read_size_a = length ;
        if(data){
            memcpy(data, rbBuf->bufferAddr + rbBuf->head, Read_size_a);
        }
        rbBuf->length -= length ;//记录剩余数据量
        rbBuf->head += Read_size_a ;//重新定位头指针位置
        if(rbBuf->head == rbBuf->bufferSize)
            rbBuf->head = 0 ;//如果读取数据后头指针刚好写到数组尾部，则回到开头，防止越位
    }
    //HET_LOGD("rb_pop %s %d -> %d \r\n",rbBuf->name, oldsize,rbBuf->length);
    return length;
}

size_t rb_size(RingBuffer *rbBuf) {
    return rbBuf->length;
}
size_t rb_max(RingBuffer *rbBuf) {
    if(!rbBuf){
        //printf("rb_max fail\r\n");
        return 0;
    }
    return rbBuf->bufferSize;
}
#if 0
int main() {
    RingBuffer *rbBuf = createRingBuffer(1024);
    setMinValue(rbBuf, 100);

    char data[512];
    memset(data, 'A', 512);
    push(rbBuf, data, 512);

    char readData[256];
    pop(rbBuf, readData, 256);

    for (size_t i = 0; i < 256; ++i) {
        printf("%c", readData[i]);
    }
    printf("\n");

    destroyRingBuffer(rbBuf);
    return 0;
}
#endif